<template>
    <div>
        <!-- 面包屑导航区 -->
        <el-breadcrumb separator-class="el-icon-arrow-right">
            <el-breadcrumb-item :to="{ path: '/home' }">首页</el-breadcrumb-item>
            <el-breadcrumb-item>权限管理</el-breadcrumb-item>
            <el-breadcrumb-item>角色列表</el-breadcrumb-item>
        </el-breadcrumb>
        <!-- 卡片视图 -->
        <el-card>
            <!-- 添加按钮 -->
            <el-row><el-button type="primary" @click="callSubComp">添加角色</el-button></el-row>
            <!-- 角色列表区域 -->
            <el-table :data="rolesList" :border="true" stripe>
                <!-- 展开列 -->
                <el-table-column type="expand">
                    <template slot-scope="scope">
                        <el-row :class="['bdbottom', index_1 == 0 ? 'bdtop' : '', 'vcenter']"
                            v-for="(item_1, index_1) in scope.row.children" :key="item_1.id">
                            <!-- 渲染一级权限 -->
                            <el-col :span="5">
                                <el-tag closable @close="removeRightById(scope.row, item_3.id)">{{
                                    item_1.authName
                                }}</el-tag>
                                <i class="el-icon-caret-right"></i>
                            </el-col>
                            <!-- 渲染二级权限和三级权限 -->
                            <el-col :span="19">
                                <!-- 通过 for 循环 嵌套渲染二级权限 -->
                                <el-row :class="[index_2 == 0 ? '' : 'bdtop', 'vcenter']"
                                    v-for="(item_2, index_2) in item_1.children" :key="item_2.id">
                                    <el-col :span="6">
                                        <el-tag type="success" closable
                                            @close="removeRightById(scope.row, item_3.id)">{{
                                                item_2.authName
                                            }}</el-tag>
                                        <i class="el-icon-caret-right"></i>
                                    </el-col>
                                    <el-col :span="18">
                                        <!-- 通过 for 循环 嵌套渲染三级权限 -->
                                        <el-tag type="warning" v-for="(item_3) in item_2.children" :key="item_3.id"
                                            closable @close="removeRightById(scope.row, item_3.id)">
                                            {{ item_3.authName }}
                                        </el-tag>
                                    </el-col>
                                </el-row>
                            </el-col>
                        </el-row>
                        <!-- 渲染二级权限 -->
                        <!-- <pre>{{ scope.row }}</pre> -->
                    </template>
                </el-table-column>
                <el-table-column type="index"></el-table-column>
                <el-table-column label="角色名称" prop="roleName"></el-table-column>
                <el-table-column label="角色描述" prop="roleDesc"></el-table-column>
                <el-table-column label="操作" width="300">
                    <template slot-scope="scope">
                        <!-- 修改按钮 -->
                        <el-button type="primary" @click="callSubComp(scope.row)" icon="el-icon-edit"
                            size="mini">编辑</el-button>
                        <!-- 删除按钮 -->
                        <el-button type="danger" @click="delRole(scope.row)" icon="el-icon-delete"
                            size="mini">删除</el-button>
                        <!-- 分配权限按钮 -->
                        <el-tooltip effect="dark" content="分配权限" placement="top" :enterable='false'>
                            <el-button type="warning" icon="el-icon-setting" size="mini"
                                @click="showSetRightDialog(scope.row)">分配权限</el-button>
                        </el-tooltip>
                    </template>
                </el-table-column>
            </el-table>
        </el-card>
        <!-- 添加、修改角色信息对话框 -->
        <edit-and-modify ref="roleRef" :getRolesList="getRolesList"></edit-and-modify>
        <!-- 分配权限对话框 -->
        <el-dialog title="分配权限" :visible.sync="setRightDialogVisible" width="50%" @close="emptyDefKeys"
            :close-on-click-modal="false">
            <!-- 树形控件 -->
            <el-tree :data="rightsList" :props="treeProps" show-checkbox default-expand-all
                :default-checked-keys="defKeys" node-key="id" ref="treeRef">
            </el-tree>
            <!-- 底部 -->
            <span slot="footer" class="dialog-footer">
                <el-button @click="setRightDialogVisible = false">取 消</el-button>
                <el-button type="primary" @click="allotRights">确 定</el-button>
            </span>
        </el-dialog>
    </div>
</template>

<script>
import editAndModify from './editAndModifyRole.vue'
export default {
    created() {
        this.getRolesList()
    },
    components: {
        editAndModify
    },
    data() {
        return {
            rolesList: [],
            rightsList: [],
            setRightDialogVisible: false,
            treeProps: { // 树形控件属性绑定对象
                children: 'children', // 父子嵌套的属性
                label: 'authName' // 要展示的属性
            },
            defKeys: [], // 默认选中的节点的ID数组
            role: '',
        };
    },
    methods: {
        async getRolesList() { // 获取所有角色列表
            const res = await this.$http.get('/roles')
            if (res.meta.status != 200)
                return this.$message.error('获取角色列表失败')
            this.$message.success('获取角色列表成功')
            this.rolesList = res.data
        },
        // 父组件调用子组件
        callSubComp(role) {
            this.$refs['roleRef'].initFormData(role)
        },
        delRole(role) { // 调用子组件的删除方法
            this.$refs['roleRef'].delRole(role)
        },
        removeRightById(role, rightID) { // 删除权限信息
            this.$refs['roleRef'].removeRightById(role, rightID)
        },
        async showSetRightDialog(role) {
            this.role = role
            // 获取所有权限数据
            const res = await this.$http.get('rights/' + 'tree')
            if (res.meta.status != 200) {
                return this.$message.error('获取权限列表失败')
            }
            this.$message.success('获取权限列表成功')
            this.rightsList = res.data
            this.getDefRights(role, this.defKeys)
            // 勾选用户已有权限
            this.setRightDialogVisible = true
        },
        // 递归的形式
        getDefRights(node, array) {
            if (!node.children) { // 如果是权限结点，则把权限id存到数组中
                console.log('权限结点-> ' + JSON.stringify(node));
                return array.push(node.id)
            }
            // 遍历每一层的子结点，再递归调用该方法去判断每个子结点的children属性
            node.children.forEach(item => {
                this.getDefRights(item, array)
            })
        },
        emptyDefKeys() { // 监听分配权限对话框的关闭事件
            console.log('defKeys数组清空前->' + this.defKeys);
            this.defKeys = []
            console.log('defKeys数组清空后->' + this.defKeys);
        },
        // 点击为角色分配权限
        async allotRights() {
            const keys = [
                ...this.$refs.treeRef.getCheckedKeys(),
                ...this.$refs.treeRef.getHalfCheckedKeys()
            ]
            console.log('更新后的权限Str' + keys.join(','));
            const res = await this.$http.post(`roles/${this.role.id}/rights`, {
                rids: keys.join(',')
            })
            if (res.meta.status != 200) {
                this.$message.error('用户权限更新失败')
                this.setRightDialogVisible = false
                return
            }
            this.$message.success('用户权限更新成功')
            this.getRolesList()
            this.setRightDialogVisible = false
        },
    },
};
</script>

<style lang="less" scoped>
.el-tag {
    margin: 7px;
}

.bdtop {
    border-top: 1px solid #eee;
}

.bdbottom {
    border-bottom: 1px solid #eee;
}

.vcenter {
    display: flex;
    align-items: center;
}
</style>